import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;

// 豆子类
class Pellet {
    private int x, y;
    private static final int SIZE = 10;
    private boolean visible;

    public Pellet(int x, int y) {
        this.x = x;
        this.y = y;
        this.visible = true;
    }

    public void draw(Graphics g) {
        if (visible) {
            g.setColor(Color.YELLOW);
            g.fillOval(x, y, SIZE, SIZE);
        }
    }

    public boolean isVisible() {
        return visible;
    }

    public void setVisible(boolean visible) {
        this.visible = visible;
    }

    public Rectangle getBounds() {
        return new Rectangle(x, y, SIZE, SIZE);
    }
}

// 玩家类
class Player implements Runnable {
    private int x, y;
    private static final int SPEED = 3;
    private static final int SIZE = 20;
    private volatile boolean running = true;
    private Direction direction = Direction.STOP;
    private int score = 0;

    enum Direction {
        UP, DOWN, LEFT, RIGHT, STOP
    }

    public Player(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void move() {
        switch (direction) {
            case UP: y = Math.max(0, y - SPEED); break;
            case DOWN: y = Math.min(400 - SIZE, y + SPEED); break;
            case LEFT: x = Math.max(0, x - SPEED); break;
            case RIGHT: x = Math.min(600 - SIZE, x + SPEED); break;
        }
    }

    public void setDirection(Direction direction) {
        this.direction = direction;
    }

    public Rectangle getBounds() {
        return new Rectangle(x, y, SIZE, SIZE);
    }

    @Override
    public void run() {
        while (running) {
            move();
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

    public void stop() {
        running = false;
    }

    public void addScore() {
        score += 10;
    }

    public int getScore() {
        return score;
    }

    public void draw(Graphics g) {
        g.setColor(Color.BLUE);
        g.fillRect(x, y, SIZE, SIZE);
    }
}

// 主游戏面板
public class PacmanGame extends JPanel implements Runnable {
    private Player player;
    private CopyOnWriteArrayList<Pellet> pellets = new CopyOnWriteArrayList<>();
    private Random random = new Random();
    private boolean gameRunning = true;

    public PacmanGame() {
        setPreferredSize(new Dimension(600, 400));
        setBackground(Color.BLACK);
        initializePlayer();
        generatePellets(30);
        addKeyListener(new KeyControl());
        setFocusable(true);
    }

    private void initializePlayer() {
        player = new Player(300, 200);
        new Thread(player).start();
    }

    private void generatePellets(int count) {
        for (int i = 0; i < count; i++) {
            int x = random.nextInt(580) + 10;
            int y = random.nextInt(360) + 10;
            pellets.add(new Pellet(x, y));
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        player.draw(g);
        pellets.forEach(p -> p.draw(g));
        g.setColor(Color.WHITE);
        g.drawString("Score: " + player.getScore(), 10, 20);
    }

    @Override
    public void run() {
        while (gameRunning) {
            checkCollisions();
            repaint();
            try {
                Thread.sleep(16);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

    private void checkCollisions() {
        pellets.removeIf(pellet -> {
            if (pellet.isVisible() && pellet.getBounds().intersects(player.getBounds())) {
                player.addScore();
                pellet.setVisible(false);
                return true;
            }
            return false;
        });

        if (pellets.isEmpty()) {
            gameRunning = false;
            JOptionPane.showMessageDialog(this, "游戏结束！最终得分: " + player.getScore());
            System.exit(0);
        }
    }

    class KeyControl extends KeyAdapter {
        @Override
        public void keyPressed(KeyEvent e) {
            switch (e.getKeyCode()) {
                case KeyEvent.VK_W: case KeyEvent.VK_UP:
                    player.setDirection(Player.Direction.UP);
                    break;
                case KeyEvent.VK_S: case KeyEvent.VK_DOWN:
                    player.setDirection(Player.Direction.DOWN);
                    break;
                case KeyEvent.VK_A: case KeyEvent.VK_LEFT:
                    player.setDirection(Player.Direction.LEFT);
                    break;
                case KeyEvent.VK_D: case KeyEvent.VK_RIGHT:
                    player.setDirection(Player.Direction.RIGHT);
                    break;
            }
        }

        @Override
        public void keyReleased(KeyEvent e) {
            player.setDirection(Player.Direction.STOP);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("吃豆子游戏");
            PacmanGame game = new PacmanGame();
            frame.add(game);
            frame.pack();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
            new Thread(game).start();
        });
    }
}